import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/wiki_config.dart';

/// 远程配置服务 - 从GitHub获取wiki配置
/// Remote Configuration Service - Fetch wiki configuration from GitHub
class ConfigService {
  static final ConfigService _instance = ConfigService._internal();
  factory ConfigService() => _instance;
  ConfigService._internal();

  final Dio _dio = Dio();

  // GitHub配置文件URL GitHub configuration file URL
  static const String _configUrl =
      'https://raw.githubusercontent.com/game-wiki-app/config/main/wiki-config.json';
  static const String _fallbackConfigUrl =
      'https://cdn.jsdelivr.net/gh/game-wiki-app/config@main/wiki-config.json';
  static const String _fallbackConfigUrl2 =
      'https://gitee.com/ymoran/wallpaper/raw/master/game.json';
  static const String _fallbackConfigUrl3 =
      'https://fastly.jsdelivr.net/gh/game-wiki-app/config@main/wiki-config.json';

  // 本地缓存键 Local cache keys
  static const String _cacheKey = 'wiki_config_cache';
  static const String _lastUpdateKey = 'config_last_update';
  static const String _versionKey = 'config_version';

  // 缓存有效期（小时） Cache validity period (hours)
  static const int _cacheValidityHours = 6;

  /// 获取Wiki配置 Get wiki configuration
  Future<WikiConfig> getWikiConfig({bool forceRefresh = false}) async {
    try {
      // 检查缓存 Check cache
      if (!forceRefresh) {
        final cachedConfig = await _getCachedConfig();
        if (cachedConfig != null && await _isCacheValid()) {
          print('Using cached configuration');
          return cachedConfig;
        }
      }

      // 从远程获取配置 Fetch configuration from remote
      try {
        final remoteConfig = await _fetchRemoteConfig();

        // 缓存配置 Cache configuration
        await _cacheConfig(remoteConfig);

        print('Using remote configuration');
        return remoteConfig;
      } catch (remoteError) {
        print(
            'Remote config fetch failed, falling back to local config: $remoteError');

        // 尝试返回缓存配置（即使过期） Try to return cached configuration (even if expired)
        final cachedConfig = await _getCachedConfig();
        if (cachedConfig != null) {
          print('Using expired cached configuration as fallback');
          return cachedConfig;
        }

        // 如果没有缓存，使用默认配置
        print('No cache available, using default configuration');
        return await _getDefaultConfig();
      }
    } catch (e) {
      print('Error getting wiki config, using default: $e');

      // 返回默认配置 Return default configuration
      print('Using default configuration');
      return await _getDefaultConfig();
    }
  }

  /// 从远程获取配置 Fetch configuration from remote
  Future<WikiConfig> _fetchRemoteConfig() async {
    final urls = [
      _configUrl,
      _fallbackConfigUrl,
      _fallbackConfigUrl2,
      _fallbackConfigUrl3,
    ];

    Exception? lastException;

    for (int i = 0; i < urls.length; i++) {
      try {
        print('Trying URL ${i + 1}/${urls.length}: ${urls[i]}');

        // 设置连接超时
        _dio.options.connectTimeout = const Duration(seconds: 10);
        _dio.options.receiveTimeout = const Duration(seconds: 10);
        _dio.options.sendTimeout = const Duration(seconds: 10);

        final response = await _dio.get(
          urls[i],
          options: Options(
            headers: {
              'Accept': 'application/json',
              'User-Agent': 'GameWikiApp/1.0',
              'Cache-Control': 'no-cache',
            },
          ),
        );

        if (response.statusCode == 200) {
          final jsonData = response.data is String
              ? json.decode(response.data)
              : response.data;
          print('Successfully fetched config from URL ${i + 1}');
          return WikiConfig.fromJson(jsonData);
        } else {
          throw Exception('HTTP ${response.statusCode}');
        }
      } catch (e) {
        lastException = e is Exception ? e : Exception(e.toString());
        print('URL ${i + 1} failed: $e');

        // 如果不是最后一个URL，继续尝试
        if (i < urls.length - 1) {
          await Future.delayed(const Duration(milliseconds: 500));
          continue;
        }
      }
    }

    // 所有URL都失败了，记录错误但不抛出异常
    print(
        'All remote URLs failed: ${lastException?.toString() ?? "Unknown error"}');
    throw lastException ?? Exception('All remote configuration URLs failed');
  }

  /// 获取缓存配置 Get cached configuration
  Future<WikiConfig?> _getCachedConfig() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final cachedJson = prefs.getString(_cacheKey);

      if (cachedJson != null) {
        final jsonData = json.decode(cachedJson);
        return WikiConfig.fromJson(jsonData);
      }
    } catch (e) {
      print('Error reading cached config: $e');
    }
    return null;
  }

  /// 缓存配置 Cache configuration
  Future<void> _cacheConfig(WikiConfig config) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final configJson = json.encode(config.toJson());

      await prefs.setString(_cacheKey, configJson);
      await prefs.setInt(_lastUpdateKey, DateTime.now().millisecondsSinceEpoch);
      await prefs.setString(_versionKey, config.version);
    } catch (e) {
      print('Error caching config: $e');
    }
  }

  /// 检查缓存是否有效 Check if cache is valid
  Future<bool> _isCacheValid() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final lastUpdate = prefs.getInt(_lastUpdateKey);

      if (lastUpdate != null) {
        final lastUpdateTime = DateTime.fromMillisecondsSinceEpoch(lastUpdate);
        final now = DateTime.now();
        final difference = now.difference(lastUpdateTime);

        return difference.inHours < _cacheValidityHours;
      }
    } catch (e) {
      print('Error checking cache validity: $e');
    }
    return false;
  }

  /// 从本地assets加载配置 Load configuration from local assets
  Future<WikiConfig> _loadLocalConfig() async {
    try {
      final configString =
          await rootBundle.loadString('assets/config/default_wiki_config.json');
      final jsonData = json.decode(configString);
      return WikiConfig.fromJson(jsonData);
    } catch (e) {
      print('Error loading local config: $e');
      return _getHardcodedDefaultConfig();
    }
  }

  /// 获取硬编码默认配置 Get hardcoded default configuration
  WikiConfig _getHardcodedDefaultConfig() {
    return WikiConfig(
      version: '1.0.0',
      lastUpdated: DateTime.now(),
      wikis: [
        WikiItem(
          id: 'terraria',
          name: 'Terraria Wiki',
          nameCn: '泰拉瑞亚百科',
          nameEn: 'Terraria Wiki',
          url: 'https://terraria.wiki.gg',
          urlCn: 'https://terraria.wiki.gg',
          description: 'Official Terraria Wiki',
          descriptionCn: '官方泰拉瑞亚百科',
          icon: 'https://terraria.wiki.gg/favicon.ico',
          category: 'Sandbox',
          tags: ['terraria', '泰拉瑞亚', 'sandbox', '沙盒'],
          isPopular: true,
          isOfficial: true,
          language: ['en', 'zh'],
          rating: 4.8,
          lastUpdated: DateTime.now(),
        ),
        WikiItem(
          id: 'minecraft',
          name: 'Minecraft Wiki',
          nameCn: '我的世界百科',
          nameEn: 'Minecraft Wiki',
          url: 'https://minecraft.wiki',
          urlCn: 'https://minecraft.wiki',
          description: 'Official Minecraft Wiki',
          descriptionCn: '官方我的世界百科',
          icon: 'https://minecraft.wiki/favicon.ico',
          category: 'Sandbox',
          tags: ['minecraft', '我的世界', 'sandbox', '沙盒'],
          isPopular: true,
          isOfficial: true,
          language: ['en', 'zh'],
          rating: 4.9,
          lastUpdated: DateTime.now(),
        ),
        WikiItem(
          id: 'genshin',
          name: 'Genshin Impact Wiki',
          nameCn: '原神百科',
          nameEn: 'Genshin Impact Wiki',
          url: 'https://genshin-impact.fandom.com',
          urlCn: 'https://genshin-impact.fandom.com',
          description: 'Genshin Impact Wiki on Fandom',
          descriptionCn: 'Fandom上的原神百科',
          icon: 'https://genshin-impact.fandom.com/favicon.ico',
          category: 'RPG',
          tags: ['genshin', '原神', 'rpg', 'mihoyo'],
          isPopular: true,
          isOfficial: false,
          language: ['en', 'zh'],
          rating: 4.7,
          lastUpdated: DateTime.now(),
        ),
      ],
      categories: [],
      features: WikiFeatures(
        searchEnabled: true,
        favoritesEnabled: true,
        historyEnabled: true,
        offlineEnabled: false,
        darkModeEnabled: true,
        multiLanguageEnabled: true,
      ),
    );
  }

  /// 获取默认配置 Get default configuration
  Future<WikiConfig> _getDefaultConfig() async {
    return await _loadLocalConfig();
  }

  /// 清除缓存 Clear cache
  Future<void> clearCache() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.remove(_cacheKey);
      await prefs.remove(_lastUpdateKey);
      await prefs.remove(_versionKey);
    } catch (e) {
      print('Error clearing cache: $e');
    }
  }

  /// 获取缓存信息 Get cache info
  Future<Map<String, dynamic>> getCacheInfo() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final lastUpdate = prefs.getInt(_lastUpdateKey);
      final version = prefs.getString(_versionKey);
      final hasCache = prefs.containsKey(_cacheKey);

      return {
        'hasCache': hasCache,
        'version': version,
        'lastUpdate': lastUpdate != null
            ? DateTime.fromMillisecondsSinceEpoch(lastUpdate).toIso8601String()
            : null,
        'isValid': await _isCacheValid(),
      };
    } catch (e) {
      print('Error getting cache info: $e');
      return {
        'hasCache': false,
        'version': null,
        'lastUpdate': null,
        'isValid': false,
      };
    }
  }

  /// 检查更新 Check for updates
  Future<bool> hasUpdates() async {
    try {
      final remoteConfig = await _fetchRemoteConfig();
      final prefs = await SharedPreferences.getInstance();
      final cachedVersion = prefs.getString(_versionKey);

      return cachedVersion != remoteConfig.version;
    } catch (e) {
      print('Error checking for updates: $e');
      return false;
    }
  }
}
